# -*- coding: utf-8 -*-
"""
Created on Sat Apr 22 15:57:57 2023

@author: simsh
"""

#!/usr/bin/python3

# Switch to a backend that doesn't need X

import matplotlib.pyplot as plt
import pandas as pd
import math
#import SMART

FIXED = 0
EXPO = 1



def add_plot(scenario_df, core_count):
    #add x-axis tick marks to graph
    # assumes core count divisible by 4
    #minTotalUtil = int(3*core_count/4)
    minTotalUtil = 3*core_count /4
    maxTotalUtil = core_count*2
    ticks=[]
    for j in range(math.floor(minTotalUtil), maxTotalUtil):
        ticks.append(j)
    #plt.set_xticks(ticks)
    #what are the utilization points we need to plot?
    util=[]
    j=0
    num_bins = math.ceil((maxTotalUtil-minTotalUtil)/BIN_SIZE)
    while j  < num_bins:
    #while j * BIN_SIZE <= maxTotalUtil:
        util.append(minTotalUtil+(j+.5)*BIN_SIZE)
        j += 1

    best_rsa = ''
    successRates = []
    j = 0

    TSA=minTotalUtil
    while j  < num_bins:
    #while j * BIN_SIZE <= maxTotalUtil:
        # I'll have to clean up column names manually
        successRates.append(scenario_df[str(j)].values[0])
        TSA += float(scenario_df[str(j)].values[0]) * BIN_SIZE
        j += 1
    # graph the success rates vs. utilization
    # no label b/c there's just one line
    RSA_duplicate = TSA / core_count
    plt.plot(util, successRates, linestyle='solid')
    plt.ylim(0, 1.02)
    plt.xlim(3*coreCount/4, 2 * coreCount)
    plt.xlabel('Utilization')
    plt.ylabel('Schedulability Ratio')
    # plt.legend(algoName)
    rsa = scenario_df['RSA'].values[0]
    rsa_string = str(round(rsa, 2))
    #rsa_string = str(round(scenario_df['rsa'].values[0], 2))

    # give graph a title and save
    full_header, name = write_header_and_name(coreCount, taskUtilRange[0], taskUtilRange[1], expected_score, slope, rsa_string)
    #plt.title(full_header + " Duplicate RSA=" + str(round(RSA_duplicate, 2)))
    plt.title(full_header)
    #plt.legend()
    # plt.show()
    plt.savefig(FOLDER_OUT + name + ".png")
    plt.clf()


def write_header_and_name(coreCount, minTaskUtil, maxTaskUtil, expected_score, slope, best_rsa):

    coreHeader=str(str(coreCount) + " Cores")
    distrib_header = "f(1)=" + str(expected_score) + ", slope=" + str(slope)
    if score_distro == FIXED:
        distrib_header = distrib_header + ", fixed"
    elif score_distro == EXPO:
        distrib_header = distrib_header + ", expo"
    util_header="Task Util. ~ U(" + str(minTaskUtil) + ", " + str(maxTaskUtil) + ")"
    rsa_header = "RSA: " + best_rsa
    full_header=coreHeader + ", " + util_header + "\n" + distrib_header + "\n" + rsa_header + ", Timeout: " + str(TIMEOUT)
    name = " ".join([coreHeader, distrib_header, util_header, best_rsa])
    return full_header, name

#FOLDER_OUT = "8Cores300/"
#FILE_IN = "May-16-1958-50Samples-oneAtATime.csv"

FOLDER_OUT = "forDefense/"
#FILE_IN = "May-10-1734-50Samples.csv"
FILE_IN = "May-16-1958-50Samples-oneAtATime.csv"

#Apr 22 2100 uses bin size 0.2?
BIN_SIZE = 0.25
#BIN_SIZE = .10

#TASK_UTIL_RANGES=[(0, .4), (0, 1)]
TASK_UTIL_RANGES=[(0, .4), (.3, .7), (.6, 1), (0, 1)]
EXPECTED_SCORES = [0.35, 0.55, 0.75]
#EXPECTED_SCORES = [0.4]
TIMEOUT = 60

df=pd.read_csv(FILE_IN)

# crazy nested for loop because I want to look at lines matching a single scenario at once
# I can't guarantee the order in which results will be in file.
for coreCount in [4,8]:
    for taskUtilRange in TASK_UTIL_RANGES:
        for expected_score in EXPECTED_SCORES:
            for score_distro in [FIXED, EXPO]:
                for slope in (0, 0.15, 0.30):
                    scenario_df = df[
                        (df['core_count'] == coreCount) &
                        (df['per_task_util_min'] == taskUtilRange[0]) &
                        (df['per_task_util_max'] == taskUtilRange[1]) &
                        (df['expected_score'] == expected_score) &
                        (df['slope'] == slope) &
                        (df['score_distro'] == score_distro) &
                        (df['timeout'] == TIMEOUT)
                        ]
                    # if we don't have any scenarios with current parameters
                    if scenario_df.shape[0] == 0:
                        continue

                    add_plot(scenario_df, coreCount)